{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1.1 First NGSolve example\n",
    "\n",
    "Let us solve the Poisson problem.\n",
    "\n",
    "$$\\text{find: } u \\in H_{0,D}^1 \\quad \\int_\\Omega \\nabla u \\nabla v = \\int_\\Omega f v, \\quad \\text{ for all } v \\in H_{0,D}^1.$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Quick steps to solution:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 1. Import NGSolve and Netgen Python modules:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import netgen.gui\n",
    "%gui tk\n",
    "from ngsolve import *\n",
    "from netgen.geom2d import unit_square"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2. Generate an unstructured mesh"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(39, 56)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))\n",
    "mesh.nv, mesh.ne   # number of vertices & elements "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Here we prescribed a maximal mesh-size of 0.2 using the `maxh` flag. \n",
    "\n",
    "* The mesh can be viewed by switching to the `Mesh` tab in the Netgen GUI. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 3. Declare a finite element space:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "133"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fes = H1(mesh, order=2, dirichlet=\"bottom|right\")\n",
    "fes.ndof  # number of unknowns in this space"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python's help system displays further documentation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on H1 in module ngsolve.comp object:\n",
      "\n",
      "class H1(FESpace)\n",
      " |   Keyword arguments can be:\n",
      " |  order: int = 1\n",
      " |    order of finite element space\n",
      " |  complex: bool = False\n",
      " |  dirichlet: regexpr\n",
      " |    Regular expression string defining the dirichlet boundary.\n",
      " |    More than one boundary can be combined by the | operator,\n",
      " |    i.e.: dirichlet = 'top|right'\n",
      " |  definedon: Region or regexpr\n",
      " |    FESpace is only defined on specific Region, created with mesh.Materials('regexpr')\n",
      " |    or mesh.Boundaries('regexpr'). If given a regexpr, the region is assumed to be\n",
      " |    mesh.Materials('regexpr').\n",
      " |  dim: int = 1\n",
      " |    Create multi dimensional FESpace (i.e. [H1]^3)\n",
      " |  dgjumps: bool = False\n",
      " |    Enable discontinuous space for DG methods, this flag is needed for DG methods,\n",
      " |    since the dofs have a different coupling then and this changes the sparsity\n",
      " |    pattern of matrices.\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      H1\n",
      " |      FESpace\n",
      " |      pybind11_builtins.pybind11_object\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __getstate__(...)\n",
      " |      __getstate__(self: ngsolve.comp.FESpace) -> tuple\n",
      " |  \n",
      " |  __init__(...)\n",
      " |      __init__(self: ngsolve.comp.H1, mesh: ngsolve.comp.Mesh, **kwargs) -> None\n",
      " |  \n",
      " |  __setstate__(...)\n",
      " |      __setstate__(self: ngsolve.comp.H1, arg0: tuple) -> None\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors defined here:\n",
      " |  \n",
      " |  __dict__\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from FESpace:\n",
      " |  \n",
      " |  ApplyM(...)\n",
      " |      ApplyM(self: ngsolve.comp.FESpace, vec: ngsolve.la.BaseVector, rho: ngsolve.fem.CoefficientFunction=None) -> None\n",
      " |      \n",
      " |      Apply mass-matrix. Available only for L2-like spaces\n",
      " |  \n",
      " |  CouplingType(...)\n",
      " |      CouplingType(self: ngsolve.comp.FESpace, dofnr: int) -> ngsolve.comp.COUPLING_TYPE\n",
      " |      \n",
      " |      get coupling type of a degree of freedom\n",
      " |  \n",
      " |  Elements(...)\n",
      " |      Elements(self: ngsolve.comp.FESpace, VOL_or_BND: ngsolve.comp.VorB=VorB.VOL) -> ngsolve.comp.FESpaceElementRange\n",
      " |  \n",
      " |  FinalizeUpdate(...)\n",
      " |      FinalizeUpdate(self: ngsolve.comp.FESpace) -> None\n",
      " |      \n",
      " |      finalize update\n",
      " |  \n",
      " |  FreeDofs(...)\n",
      " |      FreeDofs(self: ngsolve.comp.FESpace, coupling: bool=False) -> ngsolve.ngstd.BitArray\n",
      " |      \n",
      " |      Return BitArray of free (non-Dirichlet) dofs\n",
      " |      coupling=False ... all free dofs including local dofs\n",
      " |      coupling=True .... only element-boundary free dofs\n",
      " |  \n",
      " |  GetDofNrs(...)\n",
      " |      GetDofNrs(*args, **kwargs)\n",
      " |      Overloaded function.\n",
      " |      \n",
      " |      1. GetDofNrs(self: ngsolve.comp.FESpace, arg0: ngsolve.comp.ElementId) -> tuple\n",
      " |      \n",
      " |      2. GetDofNrs(self: ngsolve.comp.FESpace, arg0: ngsolve.comp.NodeId) -> tuple\n",
      " |  \n",
      " |  GetDofs(...)\n",
      " |      GetDofs(self: ngsolve.comp.FESpace, arg0: ngsolve.comp.Region) -> ngsolve.ngstd.BitArray\n",
      " |  \n",
      " |  GetFE(...)\n",
      " |      GetFE(self: ngsolve.comp.FESpace, arg0: ngsolve.comp.ElementId) -> object\n",
      " |  \n",
      " |  ParallelDofs(...)\n",
      " |      ParallelDofs(self: ngsolve.comp.FESpace) -> ngsolve.la.ParallelDofs\n",
      " |      \n",
      " |      Return dof-identification for MPI-distributed meshes\n",
      " |  \n",
      " |  Range(...)\n",
      " |      Range(self: ngsolve.comp.FESpace, component: int) -> slice\n",
      " |      \n",
      " |      Return interval of dofs of a component of a product space\n",
      " |  \n",
      " |  SetCouplingType(...)\n",
      " |      SetCouplingType(self: ngsolve.comp.FESpace, dofnr: int, coupling_type: ngsolve.comp.COUPLING_TYPE) -> None\n",
      " |      \n",
      " |      set coupling type of a degree of freedom\n",
      " |  \n",
      " |  SetDefinedOn(...)\n",
      " |      SetDefinedOn(self: ngsolve.comp.FESpace, Region: ngsolve.comp.Region) -> None\n",
      " |  \n",
      " |  SetOrder(...)\n",
      " |      SetOrder(*args, **kwargs)\n",
      " |      Overloaded function.\n",
      " |      \n",
      " |      1. SetOrder(self: ngsolve.comp.FESpace, element_type: ngsolve.fem.ET, order: int) -> None\n",
      " |      \n",
      " |      2. SetOrder(self: ngsolve.comp.FESpace, nodeid: ngsolve.comp.NodeId, order: int) -> None\n",
      " |  \n",
      " |  SolveM(...)\n",
      " |      SolveM(self: ngsolve.comp.FESpace, vec: ngsolve.la.BaseVector, rho: ngsolve.fem.CoefficientFunction=None) -> None\n",
      " |      \n",
      " |      Solve with the mass-matrix. Available only for L2-like spaces\n",
      " |  \n",
      " |  TestFunction(...)\n",
      " |      TestFunction(self: ngsolve.comp.FESpace) -> object\n",
      " |      \n",
      " |      Return a proxy to be used as a testfunction for Symbolic Integrators\n",
      " |  \n",
      " |  TnT(...)\n",
      " |      TnT(self: ngsolve.comp.FESpace) -> Tuple[object, object]\n",
      " |      \n",
      " |      Return a tuple of trial and testfunction\n",
      " |  \n",
      " |  TrialFunction(...)\n",
      " |      TrialFunction(self: ngsolve.comp.FESpace) -> object\n",
      " |      \n",
      " |      Return a proxy to be used as a trialfunction in Symbolic Integrators\n",
      " |  \n",
      " |  Update(...)\n",
      " |      Update(self: ngsolve.comp.FESpace) -> None\n",
      " |      \n",
      " |      update space after mesh-refinement\n",
      " |  \n",
      " |  UpdateDofTables(...)\n",
      " |      UpdateDofTables(self: ngsolve.comp.FESpace) -> None\n",
      " |      \n",
      " |      update dof-tables after changing polynomial order distribution\n",
      " |  \n",
      " |  __eq__(...)\n",
      " |      __eq__(self: ngsolve.comp.FESpace, arg0: ngsolve.comp.FESpace) -> bool\n",
      " |  \n",
      " |  __flags_doc__(...) from builtins.PyCapsule\n",
      " |      __flags_doc__() -> dict\n",
      " |  \n",
      " |  __special_treated_flags__(...) from builtins.PyCapsule\n",
      " |      __special_treated_flags__() -> dict\n",
      " |  \n",
      " |  __str__(...)\n",
      " |      __str__(self: ngsolve.comp.FESpace) -> str\n",
      " |  \n",
      " |  __timing__(...)\n",
      " |      __timing__(self: ngsolve.comp.FESpace) -> object\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from FESpace:\n",
      " |  \n",
      " |  components\n",
      " |      Return a list of the components of a product space\n",
      " |  \n",
      " |  globalorder\n",
      " |      query global order of space\n",
      " |  \n",
      " |  is_complex\n",
      " |  \n",
      " |  lospace\n",
      " |  \n",
      " |  mesh\n",
      " |  \n",
      " |  ndof\n",
      " |      number of degrees of freedom\n",
      " |  \n",
      " |  ndofglobal\n",
      " |      global number of dofs on MPI-distributed mesh\n",
      " |  \n",
      " |  type\n",
      " |      type of finite element space\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from pybind11_builtins.pybind11_object:\n",
      " |  \n",
      " |  __new__(*args, **kwargs) from pybind11_builtins.pybind11_type\n",
      " |      Create and return a new object.  See help(type) for accurate signature.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(fes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 4. Declare test function, trial function, and grid function \n",
    "\n",
    "* Test and trial function are symbolic objects - called `ProxyFunctions` -  that help you construct bilinear forms (and have no space to hold solutions). \n",
    "\n",
    "* `GridFunctions`, on the other hand, represent functions in the finite element space and contains memory to hold coefficient vectors."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "u = fes.TrialFunction()  # symbolic object\n",
    "v = fes.TestFunction()   # symbolic object\n",
    "gfu = GridFunction(fes)  # solution "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A shorter command for obtaining at once both trial and test variables is now available: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "u, v = fes.TnT()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 5. Define and assemble linear and bilinear forms:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = BilinearForm(fes, symmetric=True)\n",
    "a += SymbolicBFI(grad(u)*grad(v))\n",
    "a.Assemble()\n",
    "\n",
    "f = LinearForm(fes)\n",
    "f += SymbolicLFI(x*v)\n",
    "f.Assemble()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can examine the linear system in more detail:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 0.000333333\n",
      " 0.0090505\n",
      " 0.00633333\n",
      " 0.000770891\n",
      " 0.00419003\n",
      " 0.00873851\n",
      " 0.0110113\n",
      " 0.0118831\n",
      " 0.0154585\n",
      " 0.0172657\n",
      " 0.0153513\n",
      " 0.0180248\n",
      " 0.0203006\n",
      " 0.00930857\n",
      " 0.00722848\n",
      " 0.00380471\n",
      " 0.000687974\n",
      " 0.000703175\n",
      " 0.00144642\n",
      " 0.00174641\n",
      " 0.0130156\n",
      " 0.0196218\n",
      " 0.0235625\n",
      " 0.0209991\n",
      " 0.032979\n",
      " 0.0275741\n",
      " 0.0284488\n",
      " 0.0170589\n",
      " 0.0176338\n",
      " 0.0124153\n",
      " 0.0051304\n",
      " 0.00284308\n",
      " 0.00630915\n",
      " 0.0220354\n",
      " 0.0157804\n",
      " 0.0210096\n",
      " 0.0100578\n",
      " 0.0181327\n",
      " 0.0217548\n",
      " -6.66667e-05\n",
      " -3.33333e-05\n",
      " -0.000536217\n",
      " -0.000585765\n",
      " -0.00111116\n",
      " -0.0008\n",
      " -0.000766667\n",
      " -8.25863e-05\n",
      " -2.35728e-05\n",
      " -0.000125108\n",
      " -0.000290565\n",
      " -0.000209771\n",
      " -0.000451004\n",
      " -0.00040564\n",
      " -0.000661732\n",
      " -0.000800436\n",
      " -0.000504522\n",
      " -0.000864384\n",
      " -0.000967242\n",
      " -0.000947681\n",
      " -0.000970631\n",
      " -0.000782608\n",
      " -0.00113705\n",
      " -0.00131313\n",
      " -0.000661412\n",
      " -0.00146165\n",
      " -0.00135486\n",
      " -0.000642205\n",
      " -0.00125381\n",
      " -0.0012366\n",
      " -0.00157121\n",
      " -0.00143302\n",
      " -0.000438352\n",
      " -0.00133842\n",
      " -0.000991598\n",
      " -0.000377208\n",
      " -0.000778967\n",
      " -0.000731847\n",
      " -0.000237359\n",
      " -0.000666891\n",
      " -0.000536209\n",
      " -0.00039775\n",
      " -0.000251178\n",
      " -1.37451e-05\n",
      " -9.64747e-05\n",
      " -7.25997e-05\n",
      " -2.40468e-05\n",
      " -7.40193e-05\n",
      " -9.91414e-05\n",
      " -4.37045e-05\n",
      " -0.000208445\n",
      " -0.000157729\n",
      " -0.000237114\n",
      " -0.000737581\n",
      " -0.000370323\n",
      " -0.000591075\n",
      " -0.00090079\n",
      " -0.000832185\n",
      " -0.000759186\n",
      " -0.000954243\n",
      " -0.00110341\n",
      " -0.00101272\n",
      " -0.00107714\n",
      " -0.00121445\n",
      " -0.00106391\n",
      " -0.00100948\n",
      " -0.00115025\n",
      " -0.000971716\n",
      " -0.000950052\n",
      " -0.000983723\n",
      " -0.000968857\n",
      " -0.000711981\n",
      " -0.000799923\n",
      " -0.000661911\n",
      " -0.000816822\n",
      " -0.00081628\n",
      " -0.000348442\n",
      " -0.000484742\n",
      " -0.000677524\n",
      " -0.00016251\n",
      " -0.000294359\n",
      " -0.000169603\n",
      " -0.000232291\n",
      " -0.000459975\n",
      " -0.000328541\n",
      " -0.000828049\n",
      " -0.000903769\n",
      " -0.000868363\n",
      " -0.000543998\n",
      " -0.000763656\n",
      " -0.000844269\n",
      " -0.000848631\n",
      " -0.000633923\n",
      " -0.0008243\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(f.vec)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Row 0:   0: 1\n",
      "Row 1:   1: 0.829127\n",
      "Row 2:   2: 1\n",
      "Row 3:   3: 0.880753\n",
      "Row 4:   0: -0.5   4: 1.90755\n",
      "Row 5:   4: -0.559177   5: 1.91948\n",
      "Row 6:   5: -0.37742   6: 1.7799\n",
      "Row 7:   1: -0.222678   6: -0.298266   7: 1.83885\n",
      "Row 8:   1: -0.223343   8: 1.90243\n",
      "Row 9:   8: -0.375377   9: 1.75223\n",
      "Row 10:   9: -0.283322   10: 1.78161\n",
      "Row 11:   2: -0.5   10: -0.268388   11: 1.99954\n",
      "Row 12:   2: -0.5   11: -0.098129   12: 1.84322\n",
      "Row 13:   12: -0.211616   13: 1.75354\n",
      "Row 14:   13: -0.319115   14: 1.77273\n",
      "Row 15:   3: -0.359363   14: -0.356559   15: 1.85161\n",
      "Row 16:   3: -0.354152   16: 1.80192\n",
      "Row 17:   16: -0.146234   17: 1.85831\n",
      "Row 18:   17: -0.280268   18: 1.8809\n",
      "Row 19:   0: -0.5   4: -0.159147   18: -0.497592   19: 1.89108\n",
      "Row 20:   4: -0.689223   5: -0.134026   18: -0.213492   19: -0.734339   20: 3.5107\n",
      "Row 21:   5: -0.848855   6: -0.338846   20: -0.607596   21: 3.57058\n",
      "Row 22:   6: -0.76537   7: -0.325948   21: -0.590849   22: 3.53156\n",
      "Row 23:   1: -0.383106   7: -0.991955   8: -1.08169   22: -0.711434   23: 3.78819\n",
      "Row 24:   8: -0.222018   9: -0.654805   22: -0.588928   23: -0.62   24: 3.44463\n",
      "Row 25:   9: -0.438728   10: -0.852694   24: -0.516043   25: 3.57605\n",
      "Row 26:   10: -0.377206   11: -1.13302   12: -0.22963   25: -0.541968   26: 3.73524\n",
      "Row 27:   12: -0.803846   13: -0.666276   26: -0.773272   27: 3.68753\n",
      "Row 28:   13: -0.556538   14: -0.353124   27: -0.781766   28: 3.60218\n",
      "Row 29:   14: -0.74393   15: -0.202714   28: -0.943134   29: 3.72717\n",
      "Row 30:   3: -0.167237   15: -0.932971   16: -0.826096   29: -0.840918   30: 3.7686\n",
      "Row 31:   16: -0.475439   17: -1.04297   30: -0.848015   31: 3.7525\n",
      "Row 32:   17: -0.388835   18: -0.889547   20: -0.459182   31: -0.532046   32: 3.57532\n",
      "Row 33:   21: -0.763143   22: -0.54903   24: -0.350551   33: 3.66745\n",
      "Row 34:   20: -0.672842   21: -0.421292   32: -0.676988   33: -0.704385   34: 3.51434\n",
      "Row 35:   25: -0.347729   26: -0.680143   27: -0.662371   28: -0.447405   35: 3.54016\n",
      "Row 36:   29: -0.830595   30: -0.153364   31: -0.854028   32: -0.628726   34: -0.40922   36: 3.64742\n",
      "Row 37:   24: -0.492286   25: -0.878889   33: -1.07273   35: -0.76226   37: 3.75396\n",
      "Row 38:   28: -0.520216   29: -0.165884   33: -0.227614   34: -0.629613   35: -0.640254   36: -0.771484   37: -0.547794   38: 3.50286\n",
      "Row 39:   0: -0.0833333   4: 0   19: 0.0833333   39: 0.0416667\n",
      "Row 40:   0: -0.0833333   4: 0.0833333   19: 0   39: 1.73472e-18   40: 0.0416667\n",
      "Row 41:   1: -0.0318638   7: -0.0835338   23: 0.115398   41: 0.0381276\n",
      "Row 42:   1: -0.0319873   8: -0.0831334   23: 0.115121   42: 0.0380861\n",
      "Row 43:   1: -0.0743368   7: 0.120647   8: 0.120357   23: -0.166667   41: -0.0208834   42: -0.0207833   43: 0.0762138\n",
      "Row 44:   2: -0.0833333   11: 0   12: 0.0833333   44: 0.0416667\n",
      "Row 45:   2: -0.0833333   11: 0.0833333   12: 0   44: 0   45: 0.0416667\n",
      "Row 46:   3: -0.0151987   15: -0.0803559   30: 0.0955546   46: 0.0388621\n",
      "Row 47:   3: -0.0126741   16: -0.0864211   30: 0.0990952   47: 0.0395302\n",
      "Row 48:   3: -0.118919   15: 0.14025   16: 0.145447   30: -0.166777   46: -0.020089   47: -0.0216053   48: 0.0783923\n",
      "Row 49:   4: -0.0583984   5: -0.00990762   20: 0.068306   49: 0.0403755\n",
      "Row 50:   0: 0.166667   4: -0.139806   19: -0.148957   20: 0.122096   39: -0.0208333   40: -0.0208333   50: 0.0788218\n",
      "Row 51:   4: -0.119721   5: 0.103104   19: 0.0921482   20: -0.0755312   49: -0.0024769   50: -0.0164059   51: 0.0775306\n",
      "Row 52:   5: -0.0550429   6: -0.0295225   21: 0.0845653   52: 0.0368672\n",
      "Row 53:   4: 0.151595   5: -0.179629   20: -0.117774   21: 0.145809   49: -0.0145996   51: -0.023299   53: 0.0799353\n",
      "Row 54:   5: -0.0753334   6: 0.0924258   20: 0.0718059   21: -0.0888984   52: -0.00738062   53: -0.014844   54: 0.0764269\n",
      "Row 55:   6: -0.0582582   7: -0.0374957   22: 0.0957539   55: 0.0363662\n",
      "Row 56:   5: 0.117946   6: -0.132207   21: -0.107784   22: 0.122044   52: -0.0137607   54: -0.0157258   56: 0.0741162\n",
      "Row 57:   6: -0.0766627   7: 0.0872066   21: 0.0796928   22: -0.0902367   55: -0.00937392   56: -0.0131853   57: 0.0736152\n",
      "Row 58:   6: 0.107969   7: -0.131503   22: -0.114716   23: 0.13825   55: -0.0145646   57: -0.0124277   58: 0.075136\n",
      "Row 59:   1: 0.0689767   7: -0.053942   22: 0.0732872   23: -0.0883219   41: -0.00796594   43: -0.00927824   58: -0.0141145   59: 0.0768974\n",
      "Row 60:   8: -0.0282254   9: -0.0570403   24: 0.0852656   60: 0.0369571\n",
      "Row 61:   1: 0.0692111   8: -0.0460015   23: -0.0894962   24: 0.0662866   42: -0.00799682   43: -0.00930597   61: 0.0789449\n",
      "Row 62:   8: -0.159711   9: 0.119603   23: 0.154658   24: -0.114549   60: -0.0142601   61: -0.0143772   62: 0.0778159\n",
      "Row 63:   9: -0.0300697   10: -0.071478   25: 0.101548   63: 0.037192\n",
      "Row 64:   8: 0.0907882   9: -0.105614   24: -0.0776415   25: 0.0924677   60: -0.00705634   62: -0.0156407   64: 0.0730975\n",
      "Row 65:   9: -0.0993143   10: 0.118698   24: 0.10151   25: -0.120894   63: -0.0178695   64: -0.012354   65: 0.0733324\n",
      "Row 66:   10: -0.0304682   11: -0.0742233   26: 0.104691   66: 0.0373557\n",
      "Row 67:   9: 0.0772901   10: -0.0796198   25: -0.0752556   26: 0.0775854   63: -0.00751743   65: -0.0118051   67: 0.0742478\n",
      "Row 68:   10: -0.115369   11: 0.118955   25: 0.115823   26: -0.119409   66: -0.0185558   67: -0.0112965   68: 0.0744115\n",
      "Row 69:   2: 0.166667   11: -0.197946   12: -0.122045   26: 0.153325   44: -0.0208333   45: -0.0208333   69: 0.0840865\n",
      "Row 70:   10: 0.0751996   11: -0.0610862   12: 0.0550663   26: -0.0691797   66: -0.00761705   68: -0.0111829   69: -0.00967788   70: 0.0797756\n",
      "Row 71:   12: -0.0509965   13: -0.0596508   27: 0.110647   71: 0.0364792\n",
      "Row 72:   11: 0.130968   12: -0.0993327   26: -0.199191   27: 0.167556   69: -0.0286533   70: -0.00408871   72: 0.084199\n",
      "Row 73:   12: -0.0348296   13: 0.0949202   26: 0.0841386   27: -0.144229   71: -0.0149127   72: -0.0211446   73: 0.0782583\n",
      "Row 74:   13: -0.0597076   14: -0.0333842   28: 0.0930917   74: 0.0365694\n",
      "Row 75:   12: 0.0862659   13: -0.0683181   27: -0.113119   28: 0.0951715   71: -0.0127491   73: -0.00881734   75: 0.0731209\n",
      "Row 76:   13: -0.104581   14: 0.08657   27: 0.113518   28: -0.095507   74: -0.00834605   75: -0.0155307   76: 0.0732111\n",
      "Row 77:   14: -0.0676137   15: -0.0230352   29: 0.0906489   77: 0.0375189\n",
      "Row 78:   13: 0.112893   14: -0.10956   28: -0.127013   29: 0.12368   74: -0.0149269   76: -0.0132964   78: 0.0738569\n",
      "Row 79:   14: -0.0848962   15: 0.0824617   28: 0.0927755   29: -0.090341   77: -0.00575881   78: -0.0168264   79: 0.0748064\n",
      "Row 80:   14: 0.12704   15: -0.134566   29: -0.139062   30: 0.146588   77: -0.0169034   79: -0.0148566   80: 0.0768533\n",
      "Row 81:   3: 0.0750926   15: -0.0706443   29: 0.0821986   30: -0.086647   46: -0.00379968   48: -0.0149735   80: -0.0178621   81: 0.0781966\n",
      "Row 82:   16: -0.0441816   17: -0.0855914   31: 0.129773   82: 0.0385364\n",
      "Row 83:   3: 0.0716995   16: -0.0940836   30: -0.0723049   31: 0.0946889   47: -0.00316853   48: -0.0147563   83: 0.0760178\n",
      "Row 84:   16: -0.0756339   17: 0.109964   30: 0.110892   31: -0.145222   82: -0.0213979   83: -0.0149077   84: 0.075024\n",
      "Row 85:   17: -0.042337   18: -0.0557767   32: 0.0981137   85: 0.0362063\n",
      "Row 86:   16: 0.068554   17: -0.0468412   31: -0.0890017   32: 0.0672889   82: -0.0110454   84: -0.00609309   86: 0.0774179\n",
      "Row 87:   17: -0.134949   18: 0.102488   31: 0.133057   32: -0.100597   85: -0.0139442   86: -0.011205   87: 0.0750878\n",
      "Row 88:   18: -0.016011   19: -0.0567662   20: 0.0727772   88: 0.0389273\n",
      "Row 89:   18: -0.175413   19: 0.139698   20: -0.102588   32: 0.138303   88: -0.0141915   89: 0.0783959\n",
      "Row 90:   17: 0.0890484   18: -0.0662824   20: 0.0653934   32: -0.0881593   85: -0.0105842   87: -0.0116778   89: -0.0114556   90: 0.0756749\n",
      "Row 91:   4: 0.0829967   18: 0.0989431   19: -0.109457   20: -0.0724832   50: -0.014118   51: -0.00663113   88: -0.00400276   89: -0.020733   91: 0.0760824\n",
      "Row 92:   5: 0.098863   20: -0.0714262   21: -0.130771   34: 0.103334   53: -0.0216082   54: -0.0031075   92: 0.0758658\n",
      "Row 93:   18: 0.112052   20: -0.0727152   32: -0.155837   34: 0.1165   89: -0.0231203   90: -0.00489276   93: 0.0762705\n",
      "Row 94:   20: -0.072598   21: 0.086228   32: 0.0940636   34: -0.107694   92: -0.0110845   93: -0.0158389   94: 0.073108\n",
      "Row 95:   6: 0.0962552   21: -0.0854376   22: -0.110271   33: 0.0994538   56: -0.0173258   57: -0.00673795   95: 0.0735459\n",
      "Row 96:   21: -0.0716112   22: 0.0867017   33: -0.095593   34: 0.0805024   95: -0.010242   96: 0.0735987\n",
      "Row 97:   20: 0.100886   21: -0.110595   33: 0.12333   34: -0.113621   92: -0.014749   94: -0.0104725   96: -0.0136563   97: 0.0736078\n",
      "Row 98:   7: 0.0986211   22: -0.0547959   23: -0.127616   24: 0.0837913   58: -0.020448   59: -0.00420727   98: 0.0752462\n",
      "Row 99:   22: -0.112651   23: 0.107939   24: -0.0810715   33: 0.0857841   98: -0.0114561   99: 0.0729694\n",
      "Row 100:   21: 0.10422   22: -0.105922   24: 0.0954349   33: -0.093733   95: -0.0146215   96: -0.0114335   99: -0.00881178   100: 0.0727899\n",
      "Row 101:   8: 0.105926   22: 0.100081   23: -0.159263   24: -0.0467445   61: -0.00219441   62: -0.0242872   98: -0.00949172   99: -0.0155286   101: 0.0773352\n",
      "Row 102:   9: 0.0951455   24: -0.0879729   25: -0.120761   37: 0.113588   64: -0.0107629   65: -0.0130235   102: 0.0736852\n",
      "Row 103:   22: 0.110725   24: -0.106357   33: -0.135247   37: 0.130879   99: -0.0126343   100: -0.015047   103: 0.0750071\n",
      "Row 104:   24: -0.059769   25: 0.1143   33: 0.107888   37: -0.162419   102: -0.0194273   103: -0.0211775   104: 0.076059\n",
      "Row 105:   10: 0.103037   25: -0.106824   26: -0.097702   35: 0.101489   67: -0.00809987   68: -0.0176594   105: 0.0737134\n",
      "Row 106:   25: -0.113914   26: 0.110445   35: -0.125467   37: 0.128937   105: -0.0163256   106: 0.074334\n",
      "Row 107:   24: 0.07247   25: -0.0583599   35: 0.0819333   37: -0.0960434   102: -0.00896975   104: -0.00914776   106: -0.0150411   107: 0.0752212\n",
      "Row 108:   12: 0.0825381   26: -0.0476148   27: -0.13512   35: 0.100197   72: -0.0207445   73: 0.000109951   108: 0.0779035\n",
      "Row 109:   25: 0.0813281   26: -0.0894424   27: 0.0964427   35: -0.0883284   105: -0.0090465   106: -0.0112855   108: -0.0130356   109: 0.072782\n",
      "Row 110:   13: 0.084444   27: -0.109648   28: -0.056567   35: 0.0817709   75: -0.00826218   76: -0.0128488   110: 0.0741273\n",
      "Row 111:   26: 0.0923549   27: -0.112472   28: 0.0916897   35: -0.0715729   108: -0.0120137   109: -0.0110751   110: -0.00587956   111: 0.0736099\n",
      "Row 112:   14: 0.0818443   28: -0.0773065   29: -0.0724993   38: 0.0679614   78: -0.0140936   79: -0.00636744   112: 0.0767487\n",
      "Row 113:   27: 0.126424   28: -0.103037   35: -0.118365   38: 0.0949784   110: -0.0145632   111: -0.0170429   113: 0.0739925\n",
      "Row 114:   28: -0.140932   29: 0.106008   35: 0.111162   38: -0.0762371   112: -0.00403117   113: -0.0150281   114: 0.0759681\n",
      "Row 115:   15: 0.0858897   29: -0.0709417   30: -0.0969322   36: 0.0819842   80: -0.0187848   81: -0.00268759   115: 0.0770067\n",
      "Row 116:   29: -0.0802273   30: 0.0904976   36: -0.0891129   38: 0.0788427   115: -0.00544822   116: 0.0769432\n",
      "Row 117:   28: 0.14172   29: -0.168124   36: 0.145561   38: -0.119157   112: -0.0129592   114: -0.0224708   116: -0.01683   117: 0.0787321\n",
      "Row 118:   16: 0.0863197   30: -0.0550293   31: -0.112704   36: 0.0814134   83: -0.00876454   84: -0.0128154   118: 0.0772672\n",
      "Row 119:   29: 0.128896   30: -0.15041   31: 0.159351   36: -0.137837   115: -0.0150478   116: -0.0171762   118: -0.0194114   119: 0.0784519\n",
      "Row 120:   17: 0.110706   31: -0.15293   32: -0.0603088   36: 0.102532   86: -0.0056172   87: -0.0220593   120: 0.0754782\n",
      "Row 121:   30: 0.085473   31: -0.125559   32: 0.0816942   36: -0.0416078   118: -0.000941958   119: -0.0204263   120: -0.00945999   121: 0.0773763\n",
      "Row 122:   20: 0.083852   32: -0.0976556   34: -0.084342   36: 0.0981455   93: -0.013286   94: -0.00767698   122: 0.0737072\n",
      "Row 123:   31: 0.108547   32: -0.09333   34: 0.0806736   36: -0.0958903   120: -0.0161731   121: -0.0109636   122: -0.00779947   123: 0.073502\n",
      "Row 124:   21: 0.094582   33: -0.0965577   34: -0.0832128   38: 0.0851884   96: -0.00646935   97: -0.0171762   124: 0.074292\n",
      "Row 125:   24: 0.0693467   33: -0.0332607   37: -0.103733   38: 0.0676465   103: -0.0115422   104: -0.0057945   125: 0.0789452\n",
      "Row 126:   33: -0.15685   34: 0.120108   37: 0.151642   38: -0.114899   124: -0.0143338   125: -0.014391   126: 0.0774213\n",
      "Row 127:   32: 0.116423   34: -0.0970758   36: -0.128208   38: 0.108861   122: -0.0167369   123: -0.0123689   127: 0.0733718\n",
      "Row 128:   33: 0.0906254   34: -0.0997778   36: 0.098266   38: -0.0891136   124: -0.00696326   126: -0.0156931   127: -0.0153151   128: 0.0734567\n",
      "Row 129:   25: 0.0905411   35: -0.0683654   37: -0.102507   38: 0.0803318   106: -0.0171931   107: -0.00544221   129: 0.074479\n",
      "Row 130:   28: 0.0859151   35: -0.117928   37: 0.100614   38: -0.0686011   113: -0.00871649   114: -0.0127623   129: -0.0084338   130: 0.0733096\n",
      "Row 131:   29: 0.0897638   34: 0.0846056   36: -0.115247   38: -0.0591227   116: -0.00288065   117: -0.0195603   127: -0.0119   128: -0.00925136   131: 0.0757375\n",
      "Row 132:   33: 0.104161   35: 0.113475   37: -0.160957   38: -0.0566793   125: -0.00252067   126: -0.0235195   129: -0.0116491   130: -0.0167197   132: 0.0772338\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(a.mat)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 6. Solve the system:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "gfu.vec.data = \\\n",
    "    a.mat.Inverse(freedofs=fes.FreeDofs()) * f.vec\n",
    "Draw(gfu)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Dirichlet boundary condition constrains some degrees of freedom. The argument `fes.FreeDofs()` indicates that only the remaining \"free\" degrees of freedom should participate in the linear solve."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can examine the coefficient vector of solution if needed:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       0\n",
      "       0\n",
      "       0\n",
      " 0.0923019\n",
      "       0\n",
      "       0\n",
      "       0\n",
      "       0\n",
      "       0\n",
      "       0\n",
      "       0\n",
      "       0\n",
      " 0.0578968\n",
      " 0.086337\n",
      " 0.0954017\n",
      " 0.0944824\n",
      " 0.0888267\n",
      " 0.078059\n",
      " 0.0595638\n",
      " 0.0331316\n",
      " 0.0428238\n",
      " 0.0391783\n",
      " 0.0329405\n",
      " 0.0190228\n",
      " 0.0396205\n",
      " 0.0437688\n",
      " 0.0470417\n",
      " 0.0751353\n",
      " 0.0891838\n",
      " 0.0930866\n",
      " 0.0914133\n",
      " 0.0837669\n",
      " 0.0706131\n",
      " 0.0597334\n",
      " 0.0673558\n",
      " 0.0730976\n",
      " 0.0844105\n",
      " 0.0647765\n",
      " 0.0814921\n",
      "       0\n",
      " -0.00563511\n",
      "       0\n",
      "       0\n",
      " 0.0213178\n",
      "       0\n",
      " -0.0350904\n",
      " 0.00259849\n",
      " -0.00728873\n",
      " -0.00280466\n",
      "       0\n",
      " -0.00967023\n",
      " -0.0123906\n",
      "       0\n",
      " -0.0240987\n",
      " -0.0135412\n",
      "       0\n",
      " -0.0171313\n",
      " -0.0200732\n",
      " -0.00676928\n",
      " -0.0212666\n",
      "       0\n",
      " -0.0254979\n",
      " -0.00995785\n",
      "       0\n",
      " -0.0390824\n",
      " -0.013713\n",
      "       0\n",
      " -0.0269058\n",
      " -0.0176991\n",
      " -0.0333808\n",
      " -0.0238911\n",
      " -0.0243047\n",
      " -0.00442431\n",
      " -0.0102753\n",
      " -0.0146405\n",
      " -0.006598\n",
      " -0.00679179\n",
      " -0.00570818\n",
      " -0.00931926\n",
      " -0.00609179\n",
      " -0.00771503\n",
      " -0.00532019\n",
      " -0.00755367\n",
      " 0.00262541\n",
      " -0.00112314\n",
      " -0.00818072\n",
      " 0.00105745\n",
      " 0.000896631\n",
      " -0.00820643\n",
      " -0.00077952\n",
      " 0.00155068\n",
      " 0.00436689\n",
      " -0.00490164\n",
      " -0.01261\n",
      " -0.00903107\n",
      " -0.00751952\n",
      " -0.0136094\n",
      " -0.013109\n",
      " -0.00783553\n",
      " -0.0252117\n",
      " -0.00819149\n",
      " -0.00330874\n",
      " -0.00919931\n",
      " -0.0212406\n",
      " -0.00570119\n",
      " -0.00323099\n",
      " -0.0135482\n",
      " -0.0185787\n",
      " -0.0142031\n",
      " -0.0209225\n",
      " -0.013664\n",
      " -0.00405249\n",
      " -0.00922214\n",
      " -0.0103465\n",
      " -0.00890607\n",
      " -0.00277651\n",
      " -0.00675828\n",
      " -0.0105432\n",
      " -0.00452866\n",
      " -0.00654881\n",
      " -0.00618555\n",
      " -0.000547291\n",
      " -0.00262347\n",
      " -0.00559157\n",
      " -0.00883386\n",
      " -0.0116287\n",
      " -0.010581\n",
      " -0.00921447\n",
      " -0.0126657\n",
      " -0.00446274\n",
      " -0.0171414\n",
      " -0.00785433\n",
      " -0.0118158\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "print(gfu.vec)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Ways to interact with NGSolve"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* A jupyter notebook (like this one) gives you one way to interact with NGSolve. When you have a complex sequence of tasks to perform, the notebook may not be adequate.\n",
    "\n",
    "\n",
    "* You can write an entire python script in a text editor and call python on the command line. (A script of the above is provided in `poisson.py`.)\n",
    "    ```\n",
    "    python3 poisson.py\n",
    "    ```\n",
    "  \n",
    "* If you want the Netgen GUI, then use `netgen` on the command line:\n",
    "    ```\n",
    "    netgen poisson.py\n",
    "    ```\n",
    "  You can then ask for a python shell from the GUI's menu options (`Solve -> Python shell`).\n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
